package com.youlu.campus.web.user.service.impl;

import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.common.exception.BusinessException;
import com.youlu.campus.entity.QQConfigInfo;
import com.youlu.campus.entity.QQH5UserPO;
import com.youlu.campus.entity.UserOtherInfo;
import com.youlu.campus.entity.UserPO;
import com.youlu.campus.entity.VO.res.UserResponse;
import com.youlu.campus.service.activity.ActivityService;
import com.youlu.campus.service.qq.QQConfigInfoService;
import com.youlu.campus.service.utils.WebTokenUtils;
import com.youlu.campus.web.client.QQTokenService;
import com.youlu.campus.web.client.QQUserInfoResult;
import com.youlu.campus.web.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class QQUserService {


    @Autowired
    private QQConfigInfoService qqConfigInfoService;

    @Autowired
    private QQTokenService qqTokenService;

    @Autowired
    private MongoTemplate mongoTemplate;
    @Lazy
    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    @Lazy
    private ActivityService activityService;

    /**
     * 获取QQH5AccessToken
     *
     * @param code
     * @param appId
     * @param activityId
     * @param type
     * @return
     */
    public UserResponse getQQH5AccessToken(String code, String appId, String activityId, Integer type) {
        log.info(" 【qq-h5-授权】 with code:{},appId:{},activityId:{}", code, appId, activityId);
        if (StringUtils.isEmpty(code) || StringUtils.isEmpty(activityId) || StringUtils.isEmpty(appId)) {
            log.error("【qq-h5-授权】访问活动 - {} error appId - {} code - > {}", activityId, appId, code);
            throw new BusinessException("授权错误");
        }
        QQConfigInfo qqConfigInfo = qqConfigInfoService.findByAppId(appId);
        if (Objects.isNull(qqConfigInfo)) {
            throw new NullPointerException("appId -> " + appId + "不存在");
        }
        try {
            QQUserInfoResult userInfo = qqTokenService.getUserInfo(code, appId, qqConfigInfo.getAppSecret(), activityId, type);
            Query query = new Query();
            query.addCriteria(Criteria.where("openId").is(userInfo.getOpenid()));
            query.addCriteria(Criteria.where("appId").is(appId));
            QQH5UserPO qqH5UserPO = this.mongoTemplate.findOne(query, QQH5UserPO.class);
            String accountInfoId = "";
            if (Objects.isNull(qqH5UserPO)) {
                UserPO userPO = new UserPO();
                userPO.setOpenId(userInfo.getOpenid());
                userPO.setCreatedTime(new Date());
                userPO.setUnionId(userInfo.getUnionid());
                userPO = mongoTemplate.insert(userPO);
                accountInfoId = userPO.getId();
                qqH5UserPO = new QQH5UserPO();
                qqH5UserPO.setAccountInfoId(accountInfoId);
                qqH5UserPO.setGender(userInfo.getGender());
                qqH5UserPO.setOpenId(userInfo.getOpenid());
                qqH5UserPO.setAppId(appId);
                qqH5UserPO.setUnionId(userInfo.getUnionid());
                qqH5UserPO.setNickName(userInfo.getNickname());
                qqH5UserPO.setAvatarUrl(userInfo.getFigureurl_qq());
                qqH5UserPO.setProvince(userInfo.getProvince());
                qqH5UserPO.setCity(userInfo.getCity());
                this.mongoTemplate.save(qqH5UserPO);
            } else {
                accountInfoId = qqH5UserPO.getAccountInfoId();
            }
            UserResponse response = new UserResponse();
            response.setId(qqH5UserPO.getAccountInfoId());
            response.setNickName(qqH5UserPO.getNickName());
            response.setName(qqH5UserPO.getName());
            response.setOpenId(qqH5UserPO.getOpenId());
            response.setToken(WebTokenUtils.signToken(response.getOpenId()));
            redisTemplate.opsForValue().set(userService.getAccessTokenPreFix(appId, qqH5UserPO.getOpenId()),
                    WebTokenUtils.signToken(qqH5UserPO.getOpenId()), 7 * 24, TimeUnit.HOURS);
            if (Objects.nonNull(qqH5UserPO.getCheckedMobile())) {
                response.setBindMobile(qqH5UserPO.getCheckedMobile());
            }
            if (StringUtils.isNotBlank(qqH5UserPO.getProvince())) {
                response.setProvince(qqH5UserPO.getProvince());
            }
            if (StringUtils.isNotBlank(qqH5UserPO.getMobile())) {
                response.setMobile(qqH5UserPO.getMobile());
            }
            if (StringUtils.isNotBlank(qqH5UserPO.getArea())) {
                response.setArea(qqH5UserPO.getArea());
            }
            if (StringUtils.isNotBlank(qqH5UserPO.getCity())) {
                response.setCity(qqH5UserPO.getCity());
            }
            if (StringUtils.isNotBlank(qqH5UserPO.getFullAddress())) {
                response.setAddresss(qqH5UserPO.getFullAddress());
            }
            boolean get = activityService.isGetReward(activityId, accountInfoId);
            response.setRewarded(get);
            return response;
        } catch (Exception e) {
            log.error("QQ 授权H5错误 ", e);
            throw new BusinessException("授权错误");
        }

    }

    public QQH5UserPO findByAppIdAndOpenId(String appId, String openId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("appId").is(appId));
        query.addCriteria(Criteria.where("openId").is(openId));
        return this.mongoTemplate.findOne(query, QQH5UserPO.class);
    }

    public void updateAccountId(String qqUserId, String accountId) {
        Query queryQQH5 = new Query().addCriteria(Criteria.where("id").is(qqUserId));
        Update update = new Update();
        update.set("accountInfoId", accountId);
        mongoTemplate.updateFirst(queryQQH5, update, QQH5UserPO.class);
    }

    @Async
    public void updateOtherInfo(UserOtherInfo u) {
        if (Objects.isNull(u) || StringUtils.isBlank(u.getUserId())) {
            log.error(":>>> 修改用户其他信息参数错误");
            return;
        }
        Query query = new Query().addCriteria(Criteria.where("accountInfoId").is(u.getUserId()));
        Update up = new Update();
        boolean doIt = false;
        if (StringUtils.isNotBlank(u.getNickName())) {
            up.set("nickName", u.getNickName());
            doIt = true;
        }
        if (StringUtils.isNotBlank(u.getAvatarUrl())) {
            up.set("avatarUrl", u.getAvatarUrl());
            doIt = true;
        }
        if (doIt) {
            up.set("updatedTime", new Date());
            UpdateResult updateResult = mongoTemplate.updateMulti(query, up, QQH5UserPO.class);
            log.info(":>>> 修改QQH5用户信息结果:{},{}", u.getUserId(), updateResult.getModifiedCount());
        }

    }

}
